package cn.cs.mathgo.app.server;

import java.util.ArrayList;
import java.util.List;

import cn.cs.mathgo.app.entity.OAuth2ClientProperties;
import cn.cs.mathgo.app.entity.OAuth2Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.builders.InMemoryClientDetailsServiceBuilder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * 认证服务器
 * ClassName: ImoocAuthenticationServerConfig 
 * @Description: 
 * extends AuthorizationServerConfigurerAdapter 自定义token生成
 * @author lihaoyang
 * @date 2018年3月12日
 */
@Configuration
@EnableAuthorizationServer //这个注解就是实现了一个认证服务器
public class AuthenticationServerConfig extends AuthorizationServerConfigurerAdapter{

	@Autowired
	OAuth2Properties oAuth2Properties;
	//token存在redis，默认是在内存
	@Autowired
	private TokenStore tokenStore;

	/**
	 * jwt需要的两个增强器之一：将uuid转换为jwt
	 * 用 @Autowired(required = false)，这等于告诉 Spring：在找不到匹配 Bean 时也不报错。
	 */
	@Autowired
	private JwtAccessTokenConverter jwtAccessTokenConverter;

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

		//2，读取配置文件
		//判断是否配置了客户端
		InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
		for (OAuth2ClientProperties config :oAuth2Properties.getClients()) {
			builder.withClient(config.getClientId())
					.secret(config.getClientSecret())
					.accessTokenValiditySeconds(config.getAccessTokenValiditySeconds())
					.authorizedGrantTypes("password","refresh_token") //这些也可以配置也可以写死，看心情
					.scopes("all","read","write")
					.refreshTokenValiditySeconds(config.getAccessTokenValiditySeconds()); //refresh_token 有效期 可以长些
		}
	}

	/**
	 * 配置jwttokenStore
	 * @param endpoints
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints.tokenStore(tokenStore).accessTokenConverter(jwtAccessTokenConverter);
	}

	/**
	 * springSecurity 授权表达式，访问merryyou tokenkey时需要经过认证
	 * @param security
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
		security.tokenKeyAccess("isAuthenticated()");
	}


}
